﻿using System;
using System.Collections.Generic;

namespace SopCastRecorder
{
	public class ScheduleInfoManager
	{
		public enum Status
		{
			Yet,
			Doing,
			Finished
		}
		public Status Status1 { get; set; }
		private ScheduleInfo _ScheduleInfo1;
		public ScheduleInfo ScheduleInfo1
		{
			get
			{
				return this._ScheduleInfo1;
			}
			set
			{
				this._ScheduleInfo1 = value;
				this.SetStatusToFinished();
			}
		}
		public Bot Bot1 { get; set; }

		private DateTime _StartTime;
		private DateTime _EndTime;
		public DateTime StartTime
		{
			get
			{
				if (this._StartTime == DateTime.MinValue)
				{
					this.RefreshTime();
				}
				return this._StartTime;
			}
		}
		public DateTime EndTime
		{
			get
			{
				if (this._EndTime == DateTime.MinValue)
				{
					this.RefreshTime();
				}
				return this._EndTime;
			}
		}
		public void RefreshTime()
		{
			var now = DateTime.Now;
			var start = new DateTime(this.ScheduleInfo1.Date.Year, this.ScheduleInfo1.Date.Month, this.ScheduleInfo1.Date.Day, this.ScheduleInfo1.StartTime.Hour, this.ScheduleInfo1.StartTime.Minute, this.ScheduleInfo1.StartTime.Second);
			var end = new DateTime(this.ScheduleInfo1.Date.Year, this.ScheduleInfo1.Date.Month, this.ScheduleInfo1.Date.Day, this.ScheduleInfo1.EndTime.Hour, this.ScheduleInfo1.EndTime.Minute, this.ScheduleInfo1.EndTime.Second);
			if (start > end)
			{
				end = end.AddDays(1);
			}

			if (this.IsWeekly())
			{
				while (!this.RefreshWeeklyTime(now, start, end))
				{
					start = start.AddDays(1);
					end = end.AddDays(1);
				}
			}
			else
			{
				this._StartTime = start;
				this._EndTime = end;
			}
		}
		private bool IsWeekly()
		{
			return
				this.ScheduleInfo1.WeekSun ||
				this.ScheduleInfo1.WeekMon ||
				this.ScheduleInfo1.WeekTue ||
				this.ScheduleInfo1.WeekWed ||
				this.ScheduleInfo1.WeekThu ||
				this.ScheduleInfo1.WeekFri ||
				this.ScheduleInfo1.WeekSat;
		}
		private bool RefreshWeeklyTime(DateTime now, DateTime start, DateTime end)
		{
			if (!this.IsTargetWeek(start) || end <= now)
			{
				return false;
			}

			this._StartTime = start;
			this._EndTime = end;
			return true;
		}
		private bool IsTargetWeek(DateTime dt)
		{
			return
				(this.ScheduleInfo1.WeekSun && dt.DayOfWeek == DayOfWeek.Sunday) ||
				(this.ScheduleInfo1.WeekMon && dt.DayOfWeek == DayOfWeek.Monday) ||
				(this.ScheduleInfo1.WeekTue && dt.DayOfWeek == DayOfWeek.Tuesday) ||
				(this.ScheduleInfo1.WeekWed && dt.DayOfWeek == DayOfWeek.Wednesday) ||
				(this.ScheduleInfo1.WeekThu && dt.DayOfWeek == DayOfWeek.Thursday) ||
				(this.ScheduleInfo1.WeekFri && dt.DayOfWeek == DayOfWeek.Friday) ||
				(this.ScheduleInfo1.WeekSat && dt.DayOfWeek == DayOfWeek.Saturday);
		}

		public bool Start()
		{
			var now = DateTime.Now;
			if (this.Status1 == Status.Yet && this.StartTime <= now && now <= this.EndTime)
			{
				this.Bot1 = new Bot()
				{
					ScheduleInfo1 = this.ScheduleInfo1
				};
				this.Bot1.Start();
				this.Status1 = ScheduleInfoManager.Status.Doing;
				return true;
			}
			return false;
		}

		public bool Stop()
		{
			if (this.Status1 == Status.Doing && this.EndTime < DateTime.Now)
			{
				this.Bot1.End();
				this.RefreshTime();
				this.SetStatusToFinished();
				return true;
			}
			return false;
		}

		private void SetStatusToFinished()
		{
			if (!this.IsWeekly() && this.EndTime < DateTime.Now)
			{
				this.Status1 = ScheduleInfoManager.Status.Finished;
			}
			else
			{
				this.Status1 = ScheduleInfoManager.Status.Yet;
			}
		}

		public static List<ScheduleInfoManager> GetScheduleInfoManagers()
		{
			var managers = new List<ScheduleInfoManager>();
			foreach (var scheduleInfo in OptionFile.Option1.ScheduleInfoes)
			{
				if (!scheduleInfo.Enable)
				{
					continue;
				}

				var manager = new ScheduleInfoManager()
				{
					ScheduleInfo1 = scheduleInfo
				};
				managers.Add(manager);
			}
			return managers;
		}
	}
}
